package com.yanghui.dtracing.core.opentracing.reporter;

import com.yanghui.dtracing.core.PluginResourceResolver;
import com.yanghui.dtracing.core.classLoader.BreakParentClassLoader;
import com.yanghui.dtracing.core.log.ILog;
import com.yanghui.dtracing.core.log.LogManager;
import com.yanghui.dtracing.core.utils.AgentPackagePath;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class ReporterManager {

    private static ILog log = LogManager.getLogger(ReporterManager.class);

    public static Reporter loadReporters(){
        List<Reporter> reporterList = new ArrayList<>();
        CompositionReporter compositionReporter = new CompositionReporter();
        try{
            String reporterImplementPath = AgentPackagePath.getPath().getAbsolutePath()
                    + File.separator + "reporters"
                    + File.separator;
            File file = new File(reporterImplementPath);
            if(!file.exists() || file.isFile()) {
                log.info("The reporters directory does not exist");
                return new ConsoleReporter();
            }
            List<URL> jarUrls = new ArrayList<>();
            for(File child : file.listFiles()) {
                if(child.isFile() && child.getName().endsWith(".jar")){
                    jarUrls.add(new URL("file:" + child.getAbsolutePath()));
                }
            }
            /**
             * 每一个jar一个classLoad对不同的reporter进行隔离
             */
            for(URL jarUrl : jarUrls){
                BreakParentClassLoader reporterClassLoader = new BreakParentClassLoader(new URL[]{jarUrl},BreakParentClassLoader.class.getClassLoader());
                PluginResourceResolver resolver = new PluginResourceResolver();
                List<URL> reporterDefineUrls = resolver.getReportDefineResource(reporterClassLoader);
                if(reporterDefineUrls.isEmpty()) {
                    continue;
                }
                for(URL reporterDefineUrl : reporterDefineUrls){
                    List<String> reporterDefines = resolver.getDefines(reporterDefineUrl);
                    if(reporterDefines.isEmpty()) {
                        continue;
                    }
                    for(String reporterDefine : reporterDefines){
                        if(reporterDefine.trim().startsWith("#")){
                            continue;
                        }
                        Class<?> clz = reporterClassLoader.loadClass(reporterDefine);
                        Reporter reporter = (Reporter)clz.newInstance();
                        try{
                            reporter.init();
                            reporterList.add(reporter);
                            log.info("load reporter：{}",reporterDefine);
                        }catch (Exception e){
                            log.error("{} init exception",reporter.getClass().getName(),e);
                        }
                    }
                }
            }
            if(reporterList.isEmpty()){
                return new ConsoleReporter();
            }
            compositionReporter.setReporterList(reporterList);
            return compositionReporter;
        }catch (Throwable t){
            log.error("load reporter exception",t);
            return new ConsoleReporter();
        }
    }
}
